package com.ms.p2p.controller;


import com.alibaba.dubbo.config.annotation.Reference;
import com.ms.common.bean.Message;
import com.ms.common.exception.NoticeException;
import com.ms.common.utils.AppContext;
import com.ms.common.utils.CommonUtil;
import com.ms.common.utils.MsDateUtils;
import com.ms.common.utils.SpringContextHolder;
import com.ms.p2p.Constants;
import com.ms.p2p.provider.*;
import com.ms.p2p.plugin.validation.annotation.*;
import com.ms.p2p.bean.PageBean;
import com.ms.p2p.entity.account.Account;
import com.ms.p2p.entity.loan.Loan;
import com.ms.p2p.entity.loan.LoanCategory;
import com.ms.p2p.entity.member.Member;
import com.ms.p2p.enums.LoanStatus;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.beans.IntrospectionException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping({"/bid"})
public class LoanController extends BaseController {
    @Reference
    private LoanProvider loanProvider;
    @Reference
    private MemberAccountProvider memberAccountProvider;

    @Reference
    EvcProvider evcProvider;
    @Reference
    private LoanStayProvider loanStayProvider;

    @Reference
    private MemberProvider memberProvider;
    @Reference
    private LoanTenderRecordProvider loanTenderRecordProvider;
    @Reference
    private CertiFiCationProvider certificationProvider;

    @Reference
    private PasswordProvider passwordProvider;
    @Reference
    private LoanCategoryProvider loanCategoryProvider;
    @Reference
    private RedPacketProvider redPacketProvider ;
    /**
     * 到我要借款控制器
     *
     * @param request
     * @param session
     * @return
     */
    @RequestMapping("/welfare")
    public String toWelfare(HttpServletRequest request, HttpSession session) {

        return "customer/borrow/welfare";

    }
    /**
     * 到我要借款控制器
     *
     * @param request
     * @param session
     * @return
     */
    @RequestMapping("/publish")
    public String toBorrow(HttpServletRequest request, HttpSession session) {
        request.setAttribute("category",loanCategoryProvider.findById(request.getParameter("category")));
        return "customer/borrow/input";

    }
    @RequestMapping("")
    public String loan(HttpServletRequest request, HttpSession session) {
        return "customer/loan/list";

    }
    @RequestMapping({"/loanAjax"})
    @ResponseBody
    public String loanAjax(
            @RequestParam(value = "currentPage", required = false) Integer currentPage,
            @RequestParam(value = "borrowStatus", required = false) Integer borrowStatus,
            @RequestParam(value = "pay_style", required = false) Integer pay_style,
            @RequestParam(value = "timeLimitBegin", required = false) Integer timeLimitBegin,
            @RequestParam(value = "timeLimitEnd", required = false) Integer timeLimitEnd,
            @RequestParam(value = "rateBegin", required = false) Integer rateBegin,
            @RequestParam(value = "rateEnd", required = false) Integer rateEnd,
            @RequestParam(value = "time_limit", required = false) Integer time_limit,
            @RequestParam(value = "rate", required = false) String rate,
            @RequestParam(value = "lowestAccount", required = false) Integer lowestAccount,
            @RequestParam(value = "lowestAccountBegin", required = false) Integer lowestAccountBegin,
            @RequestParam(value = "lowestAccountEnd", required = false) Integer lowestAccountEnd,
            @RequestParam(value = "loanCategory", required = false) Integer loanCategory

    ){
        List<LoanCategory> types = loanCategoryProvider
                .findAll();
        PageBean borrowPage = new PageBean();
        if (currentPage != null) {
            borrowPage.setCurrentPage(currentPage);
        }
        List<Map<String, Object>> borrows = null;
        borrows = loanProvider.findPager(null, null, null, loanCategory, borrowStatus, timeLimitBegin, timeLimitEnd, rateBegin, rateEnd, lowestAccountBegin, lowestAccountEnd, pay_style, null, null, borrowPage);
        borrowPage.setTotalCount(loanProvider.findCount(null, null, null, loanCategory, borrowStatus, timeLimitBegin, timeLimitEnd, rateBegin, rateEnd, lowestAccountBegin, lowestAccountEnd, pay_style, null, null));
        HashMap ajaxMap =  new HashMap();
        FreeMarkerConfigurer freeMarkerConfigurer = SpringContextHolder.getBean("freeMarkerConfigurer");

        String templatePath = Constants.TEMPLATE_LOAN_ITEM;
        Configuration configuration = freeMarkerConfigurer.getConfiguration();
        Template template = null;
        StringBuilder content = new StringBuilder();
        try {
            template = configuration.getTemplate(templatePath, "utf-8");

            HashMap loan = new HashMap();
            loan.put("loans",borrows);
            content.append(FreeMarkerTemplateUtils.processTemplateIntoString(template, loan));
            templatePath = Constants.TEMPLATE_PAGE;
            template = configuration.getTemplate(templatePath, "utf-8");
            HashMap parameterMap = new HashMap();
            HashMap parameterMaps = new HashMap();
            parameterMaps.put("loanCategory", loanCategory);
            parameterMaps.put("borrowStatus", borrowStatus);
            parameterMaps.put("pay_style", pay_style);
            parameterMaps.put("timeLimit", time_limit);
            parameterMaps.put("timeLimitBegin", timeLimitBegin);
            parameterMaps.put("timeLimitEnd", timeLimitEnd);
            parameterMaps.put("rateBegin", rateBegin);
            parameterMaps.put("rateEnd", rateEnd);
            parameterMaps.put("lowestAccount", lowestAccount);
            parameterMaps.put("lowestAccountBegin", lowestAccountBegin);
            parameterMaps.put("lowestAccountEnd", lowestAccountEnd);
            parameterMap.put("parameterMap", parameterMaps);
            parameterMap.put("page",borrowPage);
            parameterMap.put("url","/bid/loanAjax");
            content.append(FreeMarkerTemplateUtils.processTemplateIntoString(template, parameterMap));
        } catch (IOException e) {
            e.printStackTrace();
        }
        catch (TemplateException e) {
            e.printStackTrace();
        }

        return  content.toString();


    }

    @RequestMapping({"/list"})
    public String list(HttpServletRequest request
    ) {

        return "customer/loan/list";
    }

    /**
     * 我要投资
     */
    @RequestMapping({"/detail/{borrowId}"})
    public String toLoanDetail(@PathVariable String borrowId,Model model) {
        Member member = getCurrentUser();
        Account account = new Account();
        Loan loan = loanProvider.findById(borrowId);
        if (member != null) {
            account = memberAccountProvider.findByUserId(member.getId());
            if(loan.getRed_packet_status()==1){
                PageBean page = new PageBean();
                page.setPageSize(0);
                //0表示未过期
                List redpackets =redPacketProvider.findPager(page,"0", member.getId(), loan.getTime_limit());

                model.addAttribute("redpackets", redpackets);
            }

        }


        model.addAttribute("loan", loan);
        model.addAttribute("account", account);
        model.addAttribute("borrower",memberProvider.findById(loan.getUser_id()));
        if(loan.getStatus()==2){
            model.addAttribute("last_time",Long.parseLong(loan.getNd_verify_time())*1000-System.currentTimeMillis());
        }

        //token
        String token = CommonUtil.getUUID();
        model.addAttribute("token", token);
        AppContext.setSessionAttr("TENDER_TOKEN", token);
        return "customer/loan/detail";
    }

    /**
     * 投标
     */
    @RequestMapping("/tender")
    @ResponseBody
    @Validations(requiredStrings = {
            @RequiredStringValidator(fieldName = "payPassword", message = "支付密码不能为空"),
             @RequiredStringValidator(fieldName = "account", message = "金额不能为空")

    })
    public Message tender(String token, Double account, String payPassword,
                          String loanId, String tbpwd, HttpServletRequest request, HttpSession session,String packet_id)
            throws Exception {
        String sessionToken = (String) session.getAttribute("TENDER_TOKEN");
        if (StringUtils.isBlank(sessionToken) || StringUtils.isBlank(token) || !token.equals(sessionToken)) {
          //  session.removeAttribute("TENDER_TOKEN");
            throw new NoticeException("重复提交，请刷新页面！");
        }


        String returnMsg = "投标成功";
        Member member = getCurrentUser();// 投标的用户
        // 查询实名认证状态
        String retmsg = certificationProvider.getCertiStatus(member.getId());
        if (StringUtils.isNotBlank(retmsg)) {
            throw new NoticeException(retmsg);
        }
        if (!passwordProvider.checkPayPwd(member.getId(), DigestUtils.md5Hex(payPassword))) {
            throw new NoticeException("交易密码错误");
        }

        // 获取用户的投标金额
        if (account == null || account < 0) {
            return Message.error("投标金额小于0");
        }

        Loan loan = loanProvider.findById(loanId);

        if (loan.getUser_id().equals(member.getId())) {
            throw new NoticeException("不能投自己的标！");
        }
        Account userAccount = memberAccountProvider.findByUserId(member.getId());
        if (userAccount.getBalance().compareTo(
                new BigDecimal(request.getParameter("account"))) == -1) {
            throw new NoticeException("余额不足，请充值！");
        }
        if (loan.getStatus() != LoanStatus.STATUS_3.getValue()) {
            throw new NoticeException( "借款标不在可投资状态");
        }
//
//        if (loan.getLoan_category() == 8 && !loan.getPassword().equals(member.getUser_name())) {
//            throw new NoticeException("您不是该标的的约标用户");
//        }
//        if (StringUtils.isNotBlank(loan.getTbpwd()) && !loan.getTbpwd().equals(tbpwd)) {
//            throw new NoticeException("定向密码错误");
//        }

        double lastmoney = loan.getAccount().subtract(loan.getAmount_invested()).setScale(2, 4).doubleValue();
        double amontInforce = account;// 有效金额
        if (lastmoney < account) {
            amontInforce = lastmoney;
            returnMsg = "投标成功,您的有效金额为：" + amontInforce;
        }
        if (amontInforce <= 0.0D) {
            throw new NoticeException("此标已满!");
        }
        if (loan.getLoan_category() == 1) {
            loanTenderRecordProvider.doRookie(member, loan);
        }
        if (loan.getLoan_category() == 10 && userAccount.getCollection().compareTo(loan.getLowest_wait_account()) < 0) {
            throw new NoticeException("金额小于最小待收要求");
        }


        // 不因为数据库延迟出错
        BigDecimal successAmount = new BigDecimal(amontInforce).setScale(2, 4);
        session.removeAttribute("TENDER_TOKEN");

        loanProvider.doTender(successAmount, loan, member, account, AppContext.getRemoteIp(), packet_id);

        return Message.success(returnMsg);
    }


    /**
     * 我要融资
     */
    @RequestMapping(value = {"/save"})
    @ResponseBody
    public Message save(Loan borrow)
            throws IllegalAccessException, InvocationTargetException,
            IntrospectionException {
        Member member = getCurrentUser();
        borrow.setUser_id(member.getId());
        if (borrow.getLoan_category() == 10) {
            borrow.setTime_limit(1);
            borrow.setIs_day(0);
        } else {
            borrow.setLowest_wait_account(BigDecimal.ZERO);
        }
        borrow.setAddtime(MsDateUtils.getTime());
        borrow.setAddip(AppContext.getRemoteIp());
        loanProvider.insert(borrow);
        return Message.success("借款申请成功,我们的工作人员会与您取得联系");
    }


}
